import api from '@/store/api';
import i18n from '@/i18n';
const { t } = i18n.global as any;

import { find } from 'lodash';

export const useLdapStore = defineStore('ldap', () => {
  const isServiceEnabled = ref(false);
  const ldap = ref({
    serviceEnabled: null,
    serviceAddress: null,
    bindDn: null,
    baseDn: null,
    userAttribute: null,
    groupsAttribute: null,
    roleGroups: [],
  });
  const activeDirectory = ref({
    serviceEnabled: false,
    serviceAddress: null,
    bindDn: null,
    baseDn: null,
    userAttribute: null,
    groupsAttribute: null,
    roleGroups: [],
  });
  const isActiveDirectoryEnabled = computed(
    () => activeDirectory.value.serviceEnabled,
  );
  const enabledRoleGroups = computed(() => {
    const serviceType = isActiveDirectoryEnabled.value ? activeDirectory : ldap;
    return serviceType.value.roleGroups;
  });
  const setServiceEnabled = (serviceEnabled: any) =>
    (isServiceEnabled.value = serviceEnabled);
  const setLdapProperties = ({
    ServiceEnabled,
    ServiceAddresses = [],
    Authentication = {},
    LDAPService: {
      SearchSettings: {
        BaseDistinguishedNames = [],
        UsernameAttribute = '',
        GroupsAttribute = '',
      } = {},
    } = {},
    RemoteRoleMapping = [],
  }: any) => {
    ldap.value.serviceAddress = ServiceAddresses[0];
    ldap.value.serviceEnabled = ServiceEnabled;
    ldap.value.baseDn = BaseDistinguishedNames[0];
    ldap.value.bindDn = Authentication.Username;
    ldap.value.userAttribute = UsernameAttribute;
    ldap.value.groupsAttribute = GroupsAttribute;
    ldap.value.roleGroups = RemoteRoleMapping;
  };
  const setActiveDirectoryProperties = ({
    ServiceEnabled,
    ServiceAddresses = [],
    Authentication = {},
    LDAPService: {
      SearchSettings: {
        BaseDistinguishedNames = [],
        UsernameAttribute = '',
        GroupsAttribute = '',
      } = {},
    } = {},
    RemoteRoleMapping = [],
  }: any) => {
    activeDirectory.value.serviceEnabled = ServiceEnabled;
    activeDirectory.value.serviceAddress = ServiceAddresses[0];
    activeDirectory.value.bindDn = Authentication.Username;
    activeDirectory.value.baseDn = BaseDistinguishedNames[0];
    activeDirectory.value.userAttribute = UsernameAttribute;
    activeDirectory.value.groupsAttribute = GroupsAttribute;
    activeDirectory.value.roleGroups = RemoteRoleMapping;
  };
  const getAccountSettings = async () => {
    return await api
      .get('/redfish/v1/AccountService')
      .then(({ data: { LDAP = {}, ActiveDirectory = {} } }) => {
        const ldapEnabled = LDAP.ServiceEnabled;
        const activeDirectoryEnabled = ActiveDirectory.ServiceEnabled;

        setServiceEnabled(ldapEnabled || activeDirectoryEnabled);
        setLdapProperties(LDAP);
        setActiveDirectoryProperties(ActiveDirectory);
      })
      .catch((error) => console.log(error));
  };
  const saveLdapSettings = async (properties: any) => {
    const data = { LDAP: properties };
    if (activeDirectory.value.serviceEnabled) {
      // Disable Active Directory service if enabled
      await api.patch('/redfish/v1/AccountService', {
        ActiveDirectory: { ServiceEnabled: false },
      });
    }
    return await api
      .patch('/redfish/v1/AccountService', data)
      .then(() => getAccountSettings())
      .then(() => t('pageLdap.toast.successSaveLdapSettings'))
      .catch((error) => {
        console.log(error);
        throw new Error(t('pageLdap.toast.errorSaveLdapSettings') as string);
      });
  };
  const saveActiveDirectorySettings = async (properties: any) => {
    const data = { ActiveDirectory: properties };
    if (ldap.value.serviceEnabled) {
      // Disable LDAP service if enabled
      await api.patch('/redfish/v1/AccountService', {
        LDAP: { ServiceEnabled: false },
      });
    }
    return await api
      .patch('/redfish/v1/AccountService', data)
      .then(() => getAccountSettings())
      .then(() => t('pageLdap.toast.successSaveActiveDirectorySettings'))
      .catch((error) => {
        console.log(error);
        throw new Error(
          t('pageLdap.toast.errorSaveActiveDirectorySettings') as string,
        );
      });
  };
  const saveAccountSettings = async ({
    serviceEnabled,
    serviceAddress,
    activeDirectoryEnabled,
    bindDn,
    bindPassword,
    baseDn,
    userIdAttribute,
    groupIdAttribute,
  }: any) => {
    const data: any = {
      ServiceEnabled: serviceEnabled,
      ServiceAddresses: [serviceAddress],
      Authentication: {
        Username: bindDn,
        Password: bindPassword,
      },
      LDAPService: {
        SearchSettings: {
          BaseDistinguishedNames: [baseDn],
        },
      },
    };
    if (groupIdAttribute)
      data.LDAPService.SearchSettings.GroupsAttribute = groupIdAttribute;
    if (userIdAttribute)
      data.LDAPService.SearchSettings.UsernameAttribute = userIdAttribute;

    if (activeDirectoryEnabled) {
      return await saveActiveDirectorySettings(data);
    } else {
      return await saveLdapSettings(data);
    }
  };
  const addNewRoleGroup = async ({
    groupName,
    groupPrivilege,
  }: {
    groupName: string;
    groupPrivilege: string;
  }) => {
    const data: { [index: string]: any } = {};
    const RemoteRoleMapping = [
      ...enabledRoleGroups.value,
      {
        LocalRole: groupPrivilege,
        RemoteGroup: groupName,
      },
    ];
    if (isActiveDirectoryEnabled.value) {
      data.ActiveDirectory = { RemoteRoleMapping };
    } else {
      data.LDAP = { RemoteRoleMapping };
    }
    return await api
      .patch('/redfish/v1/AccountService', data)
      .then(() => getAccountSettings())
      .then(() =>
        t('pageLdap.toast.successAddRoleGroup', {
          groupName,
        }),
      )
      .catch((error) => {
        console.log(error);
        throw new Error(t('pageLdap.toast.errorAddRoleGroup') as string);
      });
  };
  const saveRoleGroup = async ({
    groupName,
    groupPrivilege,
  }: {
    groupName: string;
    groupPrivilege: string;
  }) => {
    const data: { [index: string]: any } = {};
    const RemoteRoleMapping = enabledRoleGroups.value.map(
      (group: { RemoteGroup: any }) => {
        if (group.RemoteGroup === groupName) {
          return {
            RemoteGroup: groupName,
            LocalRole: groupPrivilege,
          };
        } else {
          return {};
        }
      },
    );
    if (isActiveDirectoryEnabled.value) {
      data.ActiveDirectory = { RemoteRoleMapping };
    } else {
      data.LDAP = { RemoteRoleMapping };
    }
    return await api
      .patch('/redfish/v1/AccountService', data)
      .then(() => getAccountSettings())
      .then(() => t('pageLdap.toast.successSaveRoleGroup', { groupName }))
      .catch((error) => {
        console.log(error);
        throw new Error(t('pageLdap.toast.errorSaveRoleGroup') as string);
      });
  };
  const deleteRoleGroup = async ({ roleGroups = [] }: { roleGroups: any }) => {
    const data: { [index: string]: any } = {};
    const RemoteRoleMapping = enabledRoleGroups.value.map(
      (group: { RemoteGroup: any }) => {
        if (find(roleGroups, { groupName: group.RemoteGroup })) {
          return null;
        } else {
          return {};
        }
      },
    );
    if (isActiveDirectoryEnabled.value) {
      data.ActiveDirectory = { RemoteRoleMapping };
    } else {
      data.LDAP = { RemoteRoleMapping };
    }
    return await api
      .patch('/redfish/v1/AccountService', data)
      .then(() => getAccountSettings())
      .then(() => t('pageLdap.toast.successDeleteRoleGroup', roleGroups.length))
      .catch((error) => {
        console.log(error);
        throw new Error(
          t('pageLdap.toast.errorDeleteRoleGroup', roleGroups.length),
        );
      });
  };
  return {
    isServiceEnabled,
    ldap,
    activeDirectory,
    isActiveDirectoryEnabled,
    enabledRoleGroups,
    setServiceEnabled,
    setLdapProperties,
    setActiveDirectoryProperties,
    getAccountSettings,
    saveLdapSettings,
    saveActiveDirectorySettings,
    saveAccountSettings,
    addNewRoleGroup,
    saveRoleGroup,
    deleteRoleGroup,
  };
});
